package com.peak.distribution.config;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.ServletWebRequest;

import com.peak.spring.boot.api.constant.ErrorMessage;
import com.peak.spring.boot.api.web.JsonMessage;
import com.peak.spring.boot.builder.web.JsonBuilder;
import com.peak.spring.boot.core.exception.ProjectException;
import com.peak.spring.boot.tools.Converts;
import com.peak.spring.boot.tools.Dates;
import com.peak.spring.boot.tools.Servlets;

import lombok.extern.slf4j.Slf4j;

@RestControllerAdvice
@Slf4j
public class SpringExceptionHandler {

	@ExceptionHandler({ Exception.class })
	public ResponseEntity<JsonMessage> processException(ServletWebRequest req, Exception e) {
		HttpServletRequest request = req.getRequest();
		// 先判断对方是不是ajax请求，返回的如果是页面就跳转到500页面去
		Map<String, String> headers = Servlets.getHeaders(request);
		Entry<String, String> html = headers.entrySet().stream()
				.filter(p -> "Accept".equalsIgnoreCase(p.getKey()) && StringUtils.contains(p.getValue(), "text/html"))
				.findAny().orElse(null);
		if (html != null) {
			try {
				req.getResponse().sendError(HttpStatus.INTERNAL_SERVER_ERROR.value());
			} catch (IOException e1) {
				log.error(e1.getMessage(), e);
			}
			return null;
		}
		// 后面才是正常的返回json错误数据
		String ip = getIP(request);
		HttpStatus status = getStatus(request);
		String errorMessage = MessageFormat.format("用户使用IP[{1}]在[{2}]的时候，请求[{3}]时出现错误：{4}", ip,
				Converts.toString(Dates.now()), request.getRequestURI(), e.getMessage());
		log.error(errorMessage, e);

		String backMessage = e.getMessage();
		if (!(e instanceof ProjectException)) {
			backMessage = ErrorMessage.FAIL.getMessage(e.getMessage());
		}

		JsonMessage json = JsonBuilder.message().fail().content(backMessage).build();
		if (!HttpStatus.FORBIDDEN.equals(status)) {
			status = HttpStatus.OK;
		}
		return new ResponseEntity<JsonMessage>(json, status);
	}

	protected String getIP(HttpServletRequest request) {
		String ip = null;
		try {
			ip = Servlets.getIp(request);
		} catch (Exception e2) {
			// 防止出现异常吧
		}
		return ip;
	}

	protected HttpStatus getStatus(HttpServletRequest request) {
		Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
		if (statusCode == null) {
			return HttpStatus.INTERNAL_SERVER_ERROR;
		}
		try {
			return HttpStatus.valueOf(statusCode);
		} catch (Exception ex) {
			return HttpStatus.INTERNAL_SERVER_ERROR;
		}
	}

}
